package com.dnjn.happiness.biz.controller;

import com.alibaba.fastjson2.JSONObject;
import com.dnjn.happiness.common.core.http.HttpUtils;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.cloud.controller.BaseController;
import com.dnjn.happiness.common.security.utils.SecurityUtils;
import com.dnjn.happiness.system.api.domain.SysUser;
import com.dnjn.happiness.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Base64;

@Slf4j
@RestController
@RequestMapping("/wxQRCode")
public class ObtainWxQRCode extends BaseController {

    private final static String wxQrCodeUrl = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode";

    private final static String accessToeknUrl = "https://api.weixin.qq.com/cgi-bin/token";

    private final static String grantType = "client_credential";

    @Value("${wx-app.appId}")
    private String appid;

    @Value("${wx-app.appSecret}")
    private String secret;


    /**
     * 将二进制转换成文件保存
     *
     * @param instreams 二进制流
     * @param imgPath   图片的保存路径
     * @param imgName   图片的名称
     * @return 1：保存正常
     * 0：保存失败
     */
    public static int saveToImgByInputStream(InputStream instreams, String imgPath, String imgName) {
        int stateInt = 1;
        if (instreams != null) {
            try {
                File file = new File(imgPath, imgName);//可以是任何图片格式.jpg,.png等
                FileOutputStream fos = new FileOutputStream(file);
                byte[] b = new byte[1024];
                int nRead = 0;
                while ((nRead = instreams.read(b)) != -1) {
                    fos.write(b, 0, nRead);
                }
                fos.flush();
                fos.close();
            } catch (Exception e) {
                stateInt = 0;
                e.printStackTrace();
            } finally {
            }
        }
        return stateInt;
    }

    /**
     * 获取小程序二维码
     *
     * @param url          官方获取二维码地址
     * @param width        二维码的宽度 int类型 默认 430
     * @param access_token
     * @param path
     * @return
     */
    public static InputStream createwxaqrcode(String url, String access_token, String path, String width) throws IOException {
        url = url + "?access_token=" + access_token;
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("path", path);
        jsonParam.put("width", width);
        InputStream instreams = doWXPost(url, jsonParam);
        if (instreams.available() == 0) {
            log.info("出错获取二维码失败！");
        }
        //保存二维码到本地 todo

        return instreams;
    }

    /**
     * 获取token
     *
     * @param url
     * @param grantType
     * @param appid
     * @param secret
     * @return
     */
    public static String getAccessToken(String url, String grantType, String appid, String secret) {
        String access_token = "";
        String tokenUrl = url + "?grant_type=" + grantType + "&appid=" + appid + "&secret=" + secret;
        Object result = HttpUtils.sendGet(tokenUrl);
        JSONObject jsons = JSONObject.parseObject(result.toString());
        String expires_in = jsons.getString("expires_in");
        if (StringUtils.isNotEmpty(expires_in) && Integer.parseInt(expires_in) == 7200) {
            //ok
            access_token = jsons.getString("access_token");
            log.info("出错获取token失败!");
        }
        return access_token;
    }

    /**
     * 请求
     *
     * @param url
     * @param jsonParam
     * @return
     */
    public static InputStream doWXPost(String url, JSONObject jsonParam) {
        InputStream instreams = null;
        HttpPost httpRequst = new HttpPost(url);// 创建HttpPost对象
        try {
            StringEntity se = new StringEntity(jsonParam.toString(), "utf-8");
            se.setContentType("application/json");
            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "UTF-8"));
            httpRequst.setEntity(se);
            HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequst);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = httpResponse.getEntity();
                if (httpEntity != null) {
                    instreams = httpEntity.getContent();
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return instreams;
    }

    /* @param instreams 二进制流
     * @param imgPath 图片的保存路径
     * @param fileName 图片的名称
     * @return str 图片保存地址
     */
    public static String saveToImgByInputStream1(InputStream instreams, String imagePath, String fileName) {
        String str = "";
//        String path = "QRimage" + getWFileDirName();
//        String linuxPath = path.replaceAll("//",File.separator);
        if (instreams != null) {
            boolean b = uploadImages(instreams, imagePath, fileName);
            if (b) {
                str = imagePath + fileName;
            }
        }
        return str;
    }

    /**
     * IO流保存图片
     *
     * @param instreams
     * @param imagePath
     * @param fileName
     * @return
     */
    public static boolean uploadImages(InputStream instreams, String imagePath, String fileName) {
        File f = new File(imagePath);
        f.setWritable(true, false);
        boolean flag = false;
        try {
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流
            File file = new File(imagePath, fileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
                try {
                    // 创建新文件
                    file.createNewFile();
                } catch (IOException e) {
                    log.info("创建新文件时出现了错误。。。");
                    e.printStackTrace();
                }
            }
            OutputStream os = new FileOutputStream(imagePath + File.separator + fileName);
            // 开始读取
            while ((len = instreams.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            // 完毕，关闭所有链接
            os.close();
            instreams.close();
            flag = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    public static File convertInputStreamToFile(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[inputStream.available()];
        inputStream.read(buffer);
        File tempFile = File.createTempFile("aaaa", ".png");
        tempFile.deleteOnExit();
        try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
            fileOutputStream.write(buffer);
            fileOutputStream.close();
        } finally {
            inputStream.close();
        }
        return tempFile;
    }

    /**
     * 根据前端token获取当前用户的二维码
     */
    @GetMapping("/getWxQrCode")
    public String getWxQrCode() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();

        //获取二维码
        String path = "pages/register?leaderId=" + sysUser.getUserId() + "&nickName=" + sysUser.getNickName();
        String result = getWxCode(path);
//    return "data:image/PNG;base64,"+result;
        return result;
    }

    /**
     * 获取二维码公共方法
     *
     * @param path
     * @return
     */
    public String getWxCode(String path) {
        //获取access_token
        String accessToken = getAccessToken(accessToeknUrl, grantType, appid, secret);
        String width = "430";
        String result = "";
        InputStream createwxaqrcode = null;
        try {
            createwxaqrcode = createwxaqrcode(wxQrCodeUrl, accessToken, path, width);
            // 将获取流转为base64格式
            byte[] data = null;
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = createwxaqrcode.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
            result = new String(Base64.getEncoder().encode(data));
        } catch (
                Exception e) {
            log.info("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (createwxaqrcode != null) {
                    createwxaqrcode.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
}
